/*
 * Copyright (C), 2002-2016, 苏宁易购电子商务有限公司
 * FileName: ModelTaskDaoServiceImpl.java
 * Author:   13075787
 * Date:     2016年7月7日 上午10:29:45
 * Description: //模块目的、功能描述      
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名             修改时间            版本号                  描述
 */
package com.suning.sawp.service.impl.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimaps;
import com.suning.framework.dal.client.DalClient;
import com.suning.sawp.intf.model.ModelConstant;
import com.suning.sawp.intf.model.ModelTaskAssignCategoryBean;
import com.suning.sawp.intf.model.ModelTaskAssignDetailsBean;
import com.suning.sawp.intf.model.ModelTaskMainBean;
import com.suning.sawp.intf.model.TaskBranchVo;
import com.suning.sawp.intf.model.TaskCateVo;
import com.suning.sawp.intf.model.TaskInfoVo;
import com.suning.sawp.service.util.BeanUtil;
import com.suning.sawp.service.util.DateUtils;

/**
 * 样机管理 <br>
 * 任务管理
 *
 * @author 13075787
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
@Service("modelTaskDaoService")
public class ModelTaskDaoServiceImpl {

    @Resource
    DalClient dalClient;

    private static final int MAX_SIZE = 2000;

    /**
     * 功能描述: <br>
     * 查询某个人是否存在要执行类型的任务
     * 
     * @param store
     * @param staffId 被分配任务的人
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public boolean queryTaskExistFlag(String storeCode, String staffId, Integer taskType, Long taskId) {
        boolean result = false;
        if (StringUtils.isNotBlank(storeCode) && StringUtils.isNotBlank(staffId)) {
            Map<String, Object> paramMap = new HashMap<String, Object>();
            // 是否具体到某个任务
            if (null != taskId) {
                paramMap.put("taskId", taskId);
            }
            paramMap.put("storeCode", storeCode);
            paramMap.put("acceptStaff", staffId);
            // 所有样机任务均为盘点类型，任务类型只区分大区和总部，前台展示不需要此
//            paramMap.put("taskType", taskType);
            // 运行状态必须是运行中
            paramMap.put("runStatus", ModelConstant.TASK_RUN_STATUS_ING);
            // 盘点任务的提交状态必须是未提交 - 其他任务默认是未提交
            paramMap.put("checkTaskStatus", ModelConstant.CHECK_TASK_STATUS_NO);
            List<Long> taskList = dalClient.queryForList("MODEL_TASK.SELECT_TASK_EXIST_ID", paramMap, Long.class);
            // 存在运行中被分配的任务
            if (CollectionUtils.isNotEmpty(taskList)) {
                for (Long theTaskId : taskList) {
                    ModelTaskMainBean taskMain = this.queryModelTaskMain(theTaskId);
                    // 任务-运行中-启用
                    if (null != taskMain && ModelConstant.TASK_RUN_STATUS_ING.equals(taskMain.getRunStatus())
                            && ModelConstant.TASK_VALID_STATUS_ENABLE.equals(taskMain.getValidStatus())) {
                        result = true;
                        break;
                    }
                }
            }
        }
        return result;
    }

    /**
     * 功能描述: <br>
     * 查询指定任务id的任务信息
     *
     * @param taskId
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public ModelTaskMainBean queryModelTaskMain(Long taskId) {
        ModelTaskMainBean result = new ModelTaskMainBean();
        if (null != taskId) {
            Map<String, Object> paramMap = new HashMap<String, Object>();
            paramMap.put("taskId", taskId);
            result = dalClient.queryForObject("MODEL_TASK.SELECT_TASK", paramMap, ModelTaskMainBean.class);
        }
        return result;
    }

    /**
     * 功能描述: <br>
     * 查询某个人是否存在要分配类型(分配品牌)任务
     *
     * @param storeCode
     * @param taskType
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public boolean queryAssigTaskExistFlag(String storeCode, Integer taskType, List<String> cateCodes, String staffId) {
        boolean result = false;
        if (StringUtils.isNotBlank(storeCode) && StringUtils.isNotBlank(staffId)) {
            Map<String, Object> paramMap = new HashMap<String, Object>();
            paramMap.put("storeCode", storeCode);
            // 所有任务更改为盘点任务，12061818
//            paramMap.put("taskType", taskType);
            // 运行状态必须是运行中
            paramMap.put("runStatus", ModelConstant.TASK_RUN_STATUS_ING);
            // 分配状态必须是未分配
            paramMap.put("assignStatus", ModelConstant.TASK_ASSIGN_STATUS_NO);
            List<Long> tasks = new ArrayList<Long>();
            // 查询被分配而产生要分配品牌的任务
            Map<String, Object> cateParamMap = new HashMap<String, Object>();
            cateParamMap.putAll(paramMap);
            cateParamMap.put("acceptStaff", staffId);
            List<Long> taskCateList = dalClient.queryForList("MODEL_TASK.SELECT_TASK_EXIST_ID_CATE", cateParamMap,
                    Long.class);
            tasks.addAll(taskCateList);
            // 根据cateCodes查询
            if (CollectionUtils.isNotEmpty(cateCodes)) {
                paramMap.put("cateCodes", cateCodes);
                List<Long> taskList = dalClient.queryForList("MODEL_TASK.SELECT_TASK_EXIST_ID", paramMap, Long.class);
                tasks.addAll(taskList);
            }
            // 存在运行中被分配的任务
            if (CollectionUtils.isNotEmpty(tasks)) {
                for (Long taskId : tasks) {
                    ModelTaskMainBean taskMain = this.queryModelTaskMain(taskId);
                    // 任务-运行中-启用
                    if (null != taskMain && ModelConstant.TASK_RUN_STATUS_ING.equals(taskMain.getRunStatus())
                            && ModelConstant.TASK_VALID_STATUS_ENABLE.equals(taskMain.getValidStatus())) {
                        result = true;
                        break;
                    }
                }
            }
        }
        return result;
    }

    /**
     * 功能描述: <br>
     * 查询执行类或分配类的任务列表(不包含分配品类的任务)
     * 
     * @param storeCode
     * @param taskType
     * @param staffId
     * @param cateCodes 被指定挂靠的品类
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public List<TaskInfoVo> queryTaskInfoList(String storeCode, Integer taskType, String staffId,
            List<String> cateCodes) {
        List<TaskInfoVo> result = null;
        if (StringUtils.isNotBlank(storeCode)) {
            result = new ArrayList<TaskInfoVo>();
            // 查询分配类的任务 + 查询被分配品类产生的要分配品牌的任务
            List<TaskInfoVo> assignTasks = this.queryAssignBranchForTask(null, storeCode, taskType, cateCodes, staffId);
            result.addAll(assignTasks);
            // 查询执行类的任务
            if (StringUtils.isNotBlank(staffId)) {
                // 执行类
                List<TaskInfoVo> oprTasks = this.queryHandleTask(null, storeCode, staffId, taskType);
                result.addAll(oprTasks);
            }
        }
        return result;
    }

    /**
     * 功能描述: <br>
     * 查询执行类的任务列表
     *
     * @param taskId
     * @param storeCode
     * @param staffId
     * @param taskType
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public List<TaskInfoVo> queryHandleTask(Long taskId, String storeCode, String staffId, Integer taskType) {
        List<TaskInfoVo> result = new ArrayList<TaskInfoVo>();
        if (StringUtils.isNotBlank(storeCode) && StringUtils.isNotBlank(staffId)) {
            Map<String, Object> paramMap = new HashMap<String, Object>();
            if (null != taskId) {
                paramMap.put("taskId", taskId);
            }
            paramMap.put("storeCode", storeCode);
            paramMap.put("acceptStaff", staffId);
//            paramMap.put("taskType", taskType);
            // 运行状态必须是运行中
            paramMap.put("runStatus", ModelConstant.TASK_RUN_STATUS_ING);
            // 展示未提交的任务
            paramMap.put("checkTaskStatus", ModelConstant.CHECK_TASK_STATUS_NO);
            // 获取执行任务列表
            List<ModelTaskAssignDetailsBean> list = dalClient.queryForList("MODEL_TASK.SELECT_TASK_ASSIGN_DETAIL",
                    paramMap, ModelTaskAssignDetailsBean.class);
            // 格式转换
            result = this.toTaskInfoVoList(list, ModelConstant.TASK_OPR_TYPE_HANDLE);
        }
        return result;
    }

    /**
     * 功能描述: <br>
     * 查询可分配的品牌列表(可以指定某个任务的)
     * 
     * @param taskId
     * @param storeCode
     * @param taskType
     * @param cateCodes
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public List<TaskInfoVo> queryAssignBranchForTask(Long taskId, String storeCode, Integer taskType,
            List<String> cateCodes, String staffId) {
        List<TaskInfoVo> result = new ArrayList<TaskInfoVo>();
        Map<String, Object> paramMap = new HashMap<String, Object>();
        // 运行状态必须是运行中
        paramMap.put("runStatus", ModelConstant.TASK_RUN_STATUS_ING);
        // 分配状态必须是未分配
        paramMap.put("assignStatus", ModelConstant.TASK_ASSIGN_STATUS_NO);
        // 查询某个任务的可分配的品类品牌
        if (null != taskId) {
            paramMap.put("taskId", taskId);
        } else {
//            paramMap.put("taskType", taskType);
        }
        // 待转化
        List<ModelTaskAssignDetailsBean> orgList = new ArrayList<ModelTaskAssignDetailsBean>();
        // 类目不为空
        if (CollectionUtils.isNotEmpty(cateCodes)) {
            Map<String, Object> assignParamMap = new HashMap<String, Object>();
            assignParamMap.putAll(paramMap);
            assignParamMap.put("storeCode", storeCode);
            // 品类
            assignParamMap.put("cateCodes", cateCodes);
            // 获取分配任务列表
            List<ModelTaskAssignDetailsBean> list = dalClient.queryForList("MODEL_TASK.SELECT_TASK_ASSIGN_DETAIL",
                    assignParamMap, ModelTaskAssignDetailsBean.class);
            orgList.addAll(list);
        }
        // 获取由于被分配无挂靠督导类目而获得的要分配的品牌
        Map<String, Object> assignParamMap = new HashMap<String, Object>();
        assignParamMap.putAll(paramMap);
        assignParamMap.put("acceptStaff", staffId);
        // 被分配品类而产生的分配品牌的任务
        List<ModelTaskAssignDetailsBean> taskCateBranchList = dalClient.queryForList(
                "MODEL_TASK.SELECT_TASK_ASSIGN_DETAIL_CATE", assignParamMap, ModelTaskAssignDetailsBean.class);
        orgList.addAll(taskCateBranchList);
        // 格式转换
        List<TaskInfoVo> assignTaskList = this.toTaskInfoVoList(orgList, ModelConstant.TASK_OPR_TYPE_BRANCH);
        result.addAll(assignTaskList);
        return result;
    }

    /**
     * 转换为展示-任务bean
     */
    private List<TaskInfoVo> toTaskInfoVoList(List<ModelTaskAssignDetailsBean> list, Integer taskOprType) {
        List<TaskInfoVo> result = new ArrayList<TaskInfoVo>();
        if (CollectionUtils.isNotEmpty(list) && null != taskOprType) {
            final Integer locTaskOprType = taskOprType;
            // 将数据库数据转为数据结构
            ImmutableMap<TaskInfoVo, Collection<ModelTaskAssignDetailsBean>> map = Multimaps
                    .index(list, new Function<ModelTaskAssignDetailsBean, TaskInfoVo>() {
                        @Override
                        public TaskInfoVo apply(ModelTaskAssignDetailsBean input) {
                            TaskInfoVo taskInfoVo = new TaskInfoVo();
                            // 任务id
                            taskInfoVo.setTaskId(String.valueOf(input.getTaskId()));
                            // 任务类型
                            taskInfoVo.setTaskType(String.valueOf(input.getTaskType()));
                            // 任务操作类型
                            taskInfoVo.setOprType(String.valueOf(locTaskOprType));
                            // 库位编码
                            taskInfoVo.setStorageCode(input.getStorageCode());
                            return taskInfoVo;
                        }
                    }).asMap();
            for (Entry<TaskInfoVo, Collection<ModelTaskAssignDetailsBean>> entry : map.entrySet()) {
                TaskInfoVo taskInfoVo = entry.getKey();
                ImmutableMap<TaskCateVo, Collection<ModelTaskAssignDetailsBean>> map2 = Multimaps
                        .index(entry.getValue(), new Function<ModelTaskAssignDetailsBean, TaskCateVo>() {
                            @Override
                            public TaskCateVo apply(ModelTaskAssignDetailsBean input) {
                                TaskCateVo taskCateVo = new TaskCateVo();
                                // 塞值-品类
                                taskCateVo.setCateCode(input.getCateCode());
                                taskCateVo.setCateName(input.getCateName());
                                return taskCateVo;
                            }
                        }).asMap();
                taskInfoVo.setCates(Lists.newArrayList(map2.keySet()));
                for (Entry<TaskCateVo, Collection<ModelTaskAssignDetailsBean>> entry1 : map2.entrySet()) {
                    ImmutableMap<TaskBranchVo, Collection<ModelTaskAssignDetailsBean>> map3 = Multimaps
                            .index(entry1.getValue(), new Function<ModelTaskAssignDetailsBean, TaskBranchVo>() {
                                @Override
                                public TaskBranchVo apply(ModelTaskAssignDetailsBean input) {
                                    TaskBranchVo taskBranchVo = new TaskBranchVo();
                                    // 塞值-品牌
                                    taskBranchVo.setBranch9Code(input.getBranch9code());
                                    taskBranchVo.setBranchName(input.getBranchName());
                                    return taskBranchVo;
                                }
                            }).asMap();
                    entry1.getKey().setBranchs(Lists.newArrayList(map3.keySet()));
                }
            }
            // 结果如下:
            List<TaskInfoVo> taskList = Lists.newArrayList(map.keySet());
            if (CollectionUtils.isNotEmpty(taskList)) {
                for (TaskInfoVo taskInfoVo : taskList) {
                    // 补充时间且排除禁用的任务
                    ModelTaskMainBean modelTaskMain = this.queryModelTaskMain(Long.valueOf(taskInfoVo.getTaskId()));
                    if (null != modelTaskMain
                            && ModelConstant.TASK_VALID_STATUS_ENABLE.equals(modelTaskMain.getValidStatus())) {
                        taskInfoVo.setStartTime(DateUtils.getDateStrByFormat(modelTaskMain.getStartTime(),
                                DateUtils.DEFAULT_POINT_DATE_PATTERN));
                        taskInfoVo.setEndTime(DateUtils.getDateStrByFormat(modelTaskMain.getEndTime(),
                                DateUtils.DEFAULT_POINT_DATE_PATTERN));
                        result.add(taskInfoVo);
                    }
                }
            }
        }
        return result;
    }

    /**
     * 功能描述: <br>
     * 查询出指定门店下所有需要分配的品类
     * 
     * @param storeCode
     * @param taskType
     * @param noCateCodes
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public List<String> queryTaskCates(String storeCode, Integer taskType, Long taskId) {
        List<String> result = null;
        if (StringUtils.isNotBlank(storeCode)) {
            Map<String, Object> paramMap = new HashMap<String, Object>();
            paramMap.put("taskId", taskId);
            paramMap.put("storeCode", storeCode);
//            paramMap.put("taskType", taskType);
            paramMap.put("runStatus", ModelConstant.TASK_RUN_STATUS_ING);
            paramMap.put("validStatus", ModelConstant.TASK_VALID_STATUS_ENABLE);
            result = dalClient.queryForList("MODEL_TASK.SELECT_TASK_ASSIGN_CATE_CODE", paramMap, String.class);
        }
        return result;
    }

    /**
     * 功能描述: <br>
     * 查询要分配的品类的任务
     * 
     * @param storeCode
     * @param taskType
     * @param noCateCodes 无挂靠督导的品类编码列表
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public List<TaskInfoVo> queryTaskCateInfoList(String storeCode, Integer taskType, List<String> noCateCodes,
            Long taskId) {
        List<TaskInfoVo> result = new ArrayList<TaskInfoVo>();
        if (StringUtils.isNotBlank(storeCode)) {
            Map<String, Object> paramMap = new HashMap<String, Object>();
            if (null != taskId) {
                paramMap.put("taskId", taskId);
            }
            paramMap.put("storeCode", storeCode);
//            paramMap.put("taskType", taskType);
            paramMap.put("runStatus", ModelConstant.TASK_RUN_STATUS_ING);
            paramMap.put("validStatus", ModelConstant.TASK_VALID_STATUS_ENABLE);
            paramMap.put("cates", noCateCodes);
            // 需要分配的品类
            List<ModelTaskAssignDetailsBean> list = dalClient.queryForList("MODEL_TASK.SELECT_TASK_ASSIGN_CATE",
                    paramMap, ModelTaskAssignDetailsBean.class);
            // 将数据库数据转为数据结构
            ImmutableMap<TaskInfoVo, Collection<ModelTaskAssignDetailsBean>> map = Multimaps
                    .index(list, new Function<ModelTaskAssignDetailsBean, TaskInfoVo>() {
                        @Override
                        public TaskInfoVo apply(ModelTaskAssignDetailsBean input) {
                            TaskInfoVo taskInfoVo = new TaskInfoVo();
                            // 任务id
                            taskInfoVo.setTaskId(String.valueOf(input.getTaskId()));
                            // 任务类型
                            taskInfoVo.setTaskType(String.valueOf(input.getTaskType()));
                            // 任务操作类型
                            taskInfoVo.setOprType(String.valueOf(ModelConstant.TASK_OPR_TYPE_CATE));
                            // 库位
                            taskInfoVo.setStorageCode(input.getStorageCode());
                            return taskInfoVo;
                        }
                    }).asMap();
            for (Entry<TaskInfoVo, Collection<ModelTaskAssignDetailsBean>> entry : map.entrySet()) {
                TaskInfoVo taskInfoVo = entry.getKey();
                ImmutableMap<TaskCateVo, Collection<ModelTaskAssignDetailsBean>> map2 = Multimaps
                        .index(entry.getValue(), new Function<ModelTaskAssignDetailsBean, TaskCateVo>() {
                            @Override
                            public TaskCateVo apply(ModelTaskAssignDetailsBean input) {
                                TaskCateVo taskCateVo = new TaskCateVo();
                                // 塞值-品类
                                taskCateVo.setCateCode(input.getCateCode());
                                taskCateVo.setCateName(input.getCateName());
                                return taskCateVo;
                            }
                        }).asMap();
                taskInfoVo.setCates(Lists.newArrayList(map2.keySet()));
            }
            // 结果如下:
            List<TaskInfoVo> taskList = Lists.newArrayList(map.keySet());
            if (CollectionUtils.isNotEmpty(taskList)) {
                for (TaskInfoVo taskInfoVo : taskList) {
                    // 补充时间且排除禁用的任务
                    ModelTaskMainBean modelTaskMain = this.queryModelTaskMain(Long.valueOf(taskInfoVo.getTaskId()));
                    if (null != modelTaskMain
                            && ModelConstant.TASK_VALID_STATUS_ENABLE.equals(modelTaskMain.getValidStatus())) {
                        taskInfoVo.setStartTime(DateUtils.getDateStrByFormat(modelTaskMain.getStartTime(),
                                DateUtils.DEFAULT_POINT_DATE_PATTERN));
                        taskInfoVo.setEndTime(DateUtils.getDateStrByFormat(modelTaskMain.getEndTime(),
                                DateUtils.DEFAULT_POINT_DATE_PATTERN));
                        result.add(taskInfoVo);
                    }
                }
            }
        }
        return result;
    }

    /**
     * 分配品类提交
     */
    @SuppressWarnings("unchecked")
    public int[] upsertAssignCateTask(List<ModelTaskAssignCategoryBean> assignCates) {
        int[] result = null;
        if (CollectionUtils.isNotEmpty(assignCates)) {
            Map<String, Object>[] batchValues = new HashMap[assignCates.size()];
            for (int i = 0; i < assignCates.size(); i++) {
                Map<String, Object> map = BeanUtil.describe(assignCates.get(i));
                batchValues[i] = map;
            }
            result = dalClient.batchUpdate("MODEL_TASK.UPSERT_MODEL_TASK_ASSIGN_CATEGORY", batchValues);
        }
        return result;
    }

    /**
     * 分配品牌提交 <br>
     * acceptStaff 必填（被分配人） <br>
     * assignStaff 必填（分配人） <br>
     * assignStatus 分配状态已分配
     */
    @SuppressWarnings("unchecked")
    public int[] updateAssignBrandTask(List<ModelTaskAssignDetailsBean> assignBrands) {
        int[] result = null;
        if (CollectionUtils.isNotEmpty(assignBrands)) {
            Map<String, Object>[] batchValues = new HashMap[assignBrands.size()];
            for (int i = 0; i < assignBrands.size(); i++) {
                Map<String, Object> map = BeanUtil.describe(assignBrands.get(i));
                batchValues[i] = map;
            }
            result = dalClient.batchUpdate("MODEL_TASK.UPDATE_MODEL_TASK_ASSIGN_DETAILS", batchValues);
        }
        return result;
    }

    /**
     * 功能描述: <br>
     * 查询盘点任务-活动结束未提交
     */
    public List<ModelTaskAssignDetailsBean> queryTaskDetailCheck(Integer index, Integer size) {
        return this.queryTaskDetailCheck(ModelConstant.TASK_RUN_STATUS_END, ModelConstant.CHECK_TASK_STATUS_NO,
                ModelConstant.TASK_ASSIGN_STATUS_DONE, index, size);
    }

    /**
     * 功能描述: <br>
     * 查询盘点任务-已分配
     */
    public List<ModelTaskAssignDetailsBean> queryTaskDetailCheck(Integer runStatus, Integer checkTaskStatus,
            Integer assignStatus, Integer index, Integer size) {
        Integer locIndex = null == index || index.intValue() < ModelConstant.NUM_ZERO ? ModelConstant.NUM_ZERO : index;
        Integer locSize = null == size ? MAX_SIZE : size;
        List<ModelTaskAssignDetailsBean> result = null;
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("startIndex", locIndex);
        paramMap.put("maxCount", locSize);
        // 任务类型-盘点,更改为所有任务都是盘点任务 12061818
//        paramMap.put("taskType", ModelConstant.TASK_TYPE_CHECK);
        // 任务分配状态
        paramMap.put("assignStatus", assignStatus);
        // 任务已结束
        paramMap.put("runStatus", runStatus);
        // 盘点未提交/已提交
        paramMap.put("checkTaskStatus", checkTaskStatus);
        result = dalClient.queryForList("MODEL_TASK.SELECT_TASK_ASSIGN_DETAIL_CHECK", paramMap,
                ModelTaskAssignDetailsBean.class);
        return result;
    }

}
